home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
ASTRONOM
/
H139.ZIP
/
RO101.ZIP
/
RO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-04
|
19KB
|
781 lines
/********************************************************/
/* */
/* ro.c main program file for ro */
/* */
/* ro version 1.10 */
/* */
/* Portions copyright (c) 1989 by Ted A. Campbell */
/* Bywater Software */
/* P. O. Box 4023 */
/* Duke Station */
/* Durham, NC 27706 */
/* */
/* Contains portions of ROFF4, Version 1.60 */
/* (c) 1983, 4 by Ernest E. Bergmann */
/* Physics, Building #16 */
/* Lehigh University */
/* Bethlehem, Pa. 18015 */
/* */
/* Contains portions of ROFF4, Version 1.61 */
/* (c) 1985 by Konrad Kwok */
/* 20 3rd Street, Section M */
/* Fariview Park, */
/* Hong Kong */
/* */
/* ro and its predecessor ROFF4 are based on */
/* the ROFF text processor described in Kernigan */
/* and Plauger's now-classic text <Software Tools> */
/* */
/* Permission is hereby granted for all commercial and */
/* non-commercial reproduction and distribution of this */
/* material provided this notice is included. */
/* */
/********************************************************/
#include "ro.h"
extern char *ro_gets();
int ro_iline = 0;
int ro_deno = 0;
/*****************MAIN************MAIN*********/
main( argc, argv )
int argc;
char **argv;
{
register int n;
int fs;
char option;
char filename[20];
struct divfd *pd;
ro_lastch = NULL;
#ifdef DEBUG
ro_debug = FALSE;
#endif
ro_verbose = FALSE;
init_defaults();
/*** First process any flags ***/
for ( n = 1; n < argc; ++n )
{
strcpy( filename, argv[ n ] );
if ( filename[0] == '-' )
{
option = filename[1];
if ( option == 'v' )
{
ro_verbose = TRUE;
fprintf( stderr, "ro, version %s \n", VERSION );
}
#ifdef DEBUG
else if ( option == 'x' )
{
ro_debug = TRUE;
ro_verbose = TRUE;
fprintf( stderr, "ro, version %s \n", VERSION );
}
#endif
else if ( option == 's' ) ro_pagestop = TRUE;
else if ( option == 'o' ) range( &filename[2] );
#ifdef POSTPROCESS
else if ( option == 'T' ) pp_init( &filename[2] );
#endif
else if ( option == 'f' ) ro_useff = TRUE;
continue;
}
}
#ifdef DEBUG
if ( ro_debug == TRUE )
{
fprintf( stderr, "DEBUG: initial .ls setting is %d. \n",
ro_lsval[0] );
}
#endif
/* Now process all files named */
fs = 0;
for ( n = 1; n < argc; ++n )
{
strcpy( filename, argv[ n ] );
if ( filename[0] != '-' )
{
if( pd = find2( filename, dlink ))
{
dclose( pd );
}
if (( instream = fopen( filename, "r" )) == NULL )
{
fprintf( stderr, "Can't open <%s> for input.\n", filename );
}
else
{
++fs; /* inc. number of files */
if ( ro_verbose == TRUE )
{
fprintf( stderr, "Processing <%s>\n", filename );
}
dolns();
}
}
}
/* No files opened; take input from stdin */
if ( fs == 0 )
{
if ( ro_verbose && ro_pagestop )
{
fprintf( stderr, "ERROR: one cannot use -s (page stop) with standard input. \n" );
}
ro_pagestop = FALSE; /* Cannot use page stop if stdin */
instream = stdin;
dolns();
}
ro_brk();
ro_vlineno = ro_plval[ 0 ];
padv();
if ( ro_useff ) ro_outc( FORMF );
#ifdef POSTPROCESS
pp_deinit(); /* Deinitialize the post-processor */
#endif
if ( ro_verbose == TRUE )
{
fprintf( stderr, "ro processing complete.\n" );
}
dsclose(); /* Close all diversions */
} /* end main() */
/****************************************/
/* do processing of lines */
/****************************************/
dolns()
{
char *pc;
struct divfd *sptr;
static char name[ 12 ];
ro_binp = 0;
while ( !feof( instream ) | ro_fptr | ro_binp )
{
ro_gets( ro_curline );
++ro_iline;
#ifdef DEBUG
if ( ro_debug == TRUE )
{
fprintf( stderr, "DEBUG: input line # %d <%s> \n",
ro_iline, ro_curline );
fprintf( stderr, "DEBUG: ro_curline[0] is <%c> (0x%x)\n",
ro_curline[0], ro_curline[0] );
}
#endif
if ( ro_curline[ 0 ] == COMMAND )
{
name[ 0 ] = ro_curline[ 1 ];
if ( class( ro_curline[ 2 ] ) == BLACK )
{
name[ 1 ] = ro_curline[ 2 ];
name[ 2 ] = '\0';
}
else
{
name[ 1 ] = '\0';
}
if ( ( pc = macq( ro_curline )) != NULL )
{
pbmac( pc, ro_curline );
}
else if ( ( sptr = find2( name, dlink )) != NULL )
{
read_div( sptr );
}
else
{
command( ro_curline );
}
}
else
{
text( ro_curline );
}
if ( feof( instream) )
{
endso();
}
}
}
char *
ro_gets( line )
char *line;
{
char *l;
l = line;
do
{
*l = ro_getch();
++l;
}
while( *(l - 1) != '\n' );
*( l - 1 ) = '\0';
#ifdef DEBUG
if ( ro_debug == TRUE )
{
fprintf( stderr, "DEBUG: ro_gets() <%s> \n", line );
}
#endif
return line;
}
char
ro_getch()
{
register int c;
static int bflag = FALSE; /* was last character BACKSLASH? */
while ( TRUE )
{
if ( ro_binp == 0 )
{
if ( feof( instream ))
{
return '\n';
}
c = fgetc( instream );
}
else
{
c = ro_backbuf[ ro_binp-- ];
}
switch ( c )
{
case EOF:
bflag = FALSE;
return '\n';
case '\r':
bflag = FALSE;
break;
case BACKSLASH:
if ( !bflag )
{
bflag = TRUE;
if ( ro_expand() == PASSBACK )
{
return BACKSLASH;
}
else
{
return ro_getch();
}
}
else
{
bflag = FALSE;
return c;
}
default:
bflag = FALSE;
return c;
}
}
}
/**************************************************************
initializes the global variables governing the execution of the
format commands.
**************************************************************/
init_defaults()
{
static time_t now;
struct tm *ltime;
initsk( ro_fill, FI_DEF); /* yes we want filled lines */
initsk( ro_lsval, LS_DEF); /* line spacing = 1 */
initsk( ro_inval, IN_DEF); /* left margin indent 0 */
initsk( ro_rmval, RM_DEF); /* right margin = page width */
initsk( ro_tcval, TC_DEF);
initsk( ro_plval, PL_DEF);
initsk( ro_m1val, M1_DEF);
initsk( ro_m2val, M2_DEF);
initsk( ro_m3val, M3_DEF);
initsk( ro_m4val, M4_DEF);
initsk( ro_scval, SC_INI);
initsk( ro_tabsiz, TS_DEF);
initsk( ro_cfval, CF_DEF);
initsk( ro_icval, IC_DEF);
ro_tival = IN_DEF; /* left margin temporary indent 0 */
ro_ceval = 0; /* next n lines to be centered - 0 */
ro_pagestop = FALSE;
ro_useff = FF_INI;
ro_firstpage = 1;
ro_lastpage = 30000; /*infinite*/
ro_adjust = JU_INI;
ro_poval = PO_DEF;
ro_curpag = 0;
ro_newpag = 1;
ro_frq = 0;
ro_frstring = ro_whstring = NULL;
ro_frval = 1;
ro_vflineno = ro_pflineno = ro_plineno = 0;
ro_vlineno = -1;
ro_bottom = ro_plval[0] - ro_m3val[0] - ro_m4val[0];
ro_outw = ro_outpos = ro_outtop = ro_outbot = ro_oldln = ro_oldbot = ro_outwrds = 0;
ro_outbuf [0] = '\0';
ro_dir = 0;
ro_eh2[0] = ro_eh3[0] = ro_ehead[0] = '\0';
ro_oh2[0] = ro_oh3[0] = ro_ohead[0] = '\0';
ro_ef2[0] = ro_ef3[0] = ro_efoot[0] = '\0';
ro_of2[0] = ro_of3[0] = ro_ofoot[0] = '\0';
memfill( ro_cptr, 2*(128-' '), 0);
memfill( ro_tptr, 2*(128-' '), 0);
ro_out2buf[ 0 ] = ro_bpos = 0;
initxu(); /* Initialize overstrike and other variables */
ro_mcnt=1;
ro_uf = ro_xf = FALSE;
memfill( ro_dbuf, LSZ, FALSE);
ro_dpos = -1;
ro_fptr = 0;
mlink = dlink = rlink = slink = NULL;
ro_kptr = ro_kline;
*ro_kline=0;
ro_keybd=FALSE;
/*** now set up some pre-defined registers ***/
time( &now );
ltime = localtime( &now );
preregister( "dy", ltime->tm_mday );
preregister( "mo", ltime->tm_mon + 1 );
preregister( "yr", ltime->tm_year );
preregister( "%", ro_curpag );
}
/**************************************************************
performs the formatting command returned by comtyp -sets global
variables ( indenting, underlining, etc. )
**************************************************************/
command( line )
char *line;
{
int c_type; /* command type */
int arg_val; /* argument value, if any */
static int arg_typ; /* relative (+ or -) or absolute */
char wbuf[20];
c_type = comtyp (line);
#ifdef DEBUG
if ( ro_debug == TRUE )
{
fprintf( stderr, "DEBUG: command is %d \n", c_type );
}
#endif
if ( c_type == UNKNOWN )
{
if ( ro_verbose == TRUE )
fprintf( stderr, "%s: unknown command \n", line);
return;
}
arg_val = get_val( line, &arg_typ );
#ifdef DEBUG
if ( ro_debug == TRUE )
{
fprintf( stderr, "DEBUG: get_val returned arg_val = %d, arg_typ = %c\n",
arg_val, arg_typ );
fprintf( stderr, "DEBUG: c_type is now %d \n", c_type );
}
#endif
switch ( c_type )
{
case EM :
case IG :
break; /* ignore remark */
case FI : /* filled lines */
ro_brk();
ro_fill[0] = YES;
break;
case NF: /* non-filled lines */
ro_brk();
ro_fill[0] = NO;
break;
case AD : /* adjusted (justified) lines */
ro_adjust = TRUE;
break;
case NA : /* non-adjusted lines */
ro_adjust = FALSE;
break;
case BR : /* just cause a break */
ro_brk();
break;
case LS : /* set line spacing value */
setS( ro_lsval, arg_val, arg_typ, LS_DEF, 1, HUGE );
break;
case TI : /* set temporary left indent */
ro_brk();
set( &ro_tival, arg_val, arg_typ, TI_DEF, 0, ro_rmval );
break;
case IN : /* set left indent */
ro_brk();
setS( ro_inval, arg_val, arg_typ, IN_DEF, 0, ro_rmval-1 );
ro_tival = ro_inval[0];
break;
case LL : /* set line length (right margin) */
setS( ro_rmval, arg_val, arg_typ, RM_DEF, ro_tival+1, 256 );
break;
case CE : /* center next arg_val lines */
ro_brk();
set( &ro_ceval, arg_val, arg_typ, CE_DEF, 0, HUGE);
break;
case SP : /* space down arg_val blank lines */
set( &ro_spval, arg_val, arg_typ, 1, 0, HUGE);
do_space ( ro_spval );
break;
case BP : /* set pageno arg_val - begin page */
ro_brk();
if(((ro_vlineno<=0)||(ro_vlineno>=ro_bottom))&&
(arg_val==NO_VAL))
{
break;
}
if ( ro_vlineno > 0 )
{
do_space (HUGE);
}
set( &ro_curpag, arg_val, arg_typ, ro_curpag+1, 0, 9999);
ro_newpag = ro_curpag;
break;
case NE : /*"need"*/
if ( arg_val == NO_VAL )
{
arg_val = 2; /*default*/
}
need( arg_val );
break;
case PL : /* set page length */
setS( ro_plval, arg_val, arg_typ, PL_DEF,
ro_m1val[0]+ro_m2val[0]+ro_m3val[0]+ro_m4val[0]+1, HUGE);
ro_bottom = ro_plval[0] - ro_m3val[0] - ro_m4val[0];
break;
case TA : /*tabsize*/
setS( ro_tabsiz, arg_val, '0', TS_DEF, 1, HUGE);
break;
case TC : /* tab character */
if ( arg_typ )
{
arg_val=arg_typ;
}
setS( ro_tcval, arg_val, '0', TC_DEF, BLANK+1, 127);
break;
case FT : /* Set font */
switch( arg_typ )
{
case 'R':
putback( '\n' );
putback( ROMAN );
putback( ESCAPE );
break;
case 'I':
putback( '\n' );
putback( ITALIC );
putback( ESCAPE );
break;
case 'B':
putback( '\n' );
putback( BOLD );
putback( ESCAPE );
break;
default:
if ( ro_verbose )
{
fprintf( stderr,
"ft: unrecognized font name \"%c\". \n",
arg_typ );
}
}
break;
case TR : /*translation string defined here*/
gettr();
break;
case DS : /*define string*/
insert();
break;
case DE : /*define macro*/
++ro_deno;
#ifdef DEBUG
if ( ro_debug == TRUE )
{
fprintf( stderr, "DEBUG: .de number %d \n",
ro_deno );
}
#endif
minsert();
break;
case NR : /*register variable*/
dovar();
break;
case DI : /*diversion to file*/
dodiv();
break;
case SO : /*source from file*/
source();
break;
case PM : /* print macro definitions */
showm();
break;
case PO : /* page offset */
set( &ro_poval, arg_val, arg_typ, 1, 0, HUGE );
break;
case TM : /* send message to terminal */
getwrd(ro_curline, wbuf); /*skip command*/
skip_blanks(ro_curline);
trunc_bl(ro_curline);
fprintf( stderr, "<%s>\n", ro_curline);
break;
#ifdef NONROFF
case M1: /* set topmost margin */
setS( ro_m1val, arg_val, arg_typ, M1_DEF, 0, HUGE);
break;
case M2: /* set second top margin */
setS( ro_m2val, arg_val, arg_typ, M2_DEF, 0, HUGE);
break;
case M3: /* set first bottom margin */
setS( ro_m3val, arg_val, arg_typ, M3_DEF, 0, HUGE);
ro_bottom = ro_plval[0] - ro_m3val[0] - ro_m4val[0];
break;
case M4: /* set bottom-most margin */
setS( ro_m4val, arg_val, arg_typ, M4_DEF, 0, HUGE);
ro_bottom = ro_plval[0] - ro_m3val[0] - ro_m4val[0];
break;
case HE : /* get header title for pages */
gettl3 ( line, ro_ehead, ro_eh2, ro_eh3 );
gettl3 ( line, ro_ohead, ro_oh2, ro_oh3 );
break;
case OH : /*get odd header title*/
gettl3 ( line, ro_ohead, ro_oh2, ro_oh3 );
break;
case EH : /*get even header title*/
gettl3 ( line, ro_ehead, ro_eh2, ro_eh3 );
break;
case FO : /* get footer title for pages */
gettl3 ( line, ro_efoot, ro_ef2, ro_ef3 );
gettl3 ( line, ro_ofoot, ro_of2, ro_of3 );
break;
case OF : /* get odd page footer title*/
gettl3 ( line, ro_ofoot, ro_of2, ro_of3 );
break;
case EF : /* get even page footer title*/
gettl3 ( line, ro_efoot, ro_ef2, ro_ef3 );
break;
case ST : /* stop(pause) at each page?*/
set( &ro_pagestop, arg_val, '0', YES, NO, YES);
break;
case BJ : /*break with right justification*/
if ( ro_fill ) /*not applicable otherwise*/
{
spread(ro_outbuf,
ro_min( ro_rmval - ro_tival, MAXLINE - 1 ) - ro_outw + 1,
ro_outwrds);
ro_brk();
}
break;
case FF : /*formfeed*/
set( &ro_useff, arg_val, '0', FF_DEF, NO, YES);
break;
case SC : /*space character*/
if ( arg_typ )
{
arg_val=arg_typ;
}
setS( ro_scval, arg_val, '0', SC_INI, BLANK, 127);
break;
case EX : /* exit (abort) */
if ( ro_verbose )
fprintf( stderr, ".ex: user abort. \n");
exit(-1); /* tac */
case CF : /*translate character flag*/
if ( arg_typ )
{
arg_val=arg_typ;
}
setS( ro_cfval, arg_val, '0', CF_DEF, BLANK+1, 127);
break;
case IC : /* insert character for macro replace */
if ( arg_typ )
{
arg_val = arg_typ;
}
setS( ro_icval, arg_val, '0', IC_DEF, BLANK+1, 127 );
break;
case SR : /* print register definitions */
showr();
break;
case SS : /* print string definitions */
showit();
break;
#endif
#ifdef DEBUG
case DB : /* debug */
set( &ro_debug, arg_val, '0', NO, NO, YES);
if ( ro_debug == TRUE )
{
fprintf( stderr, "DEBUG on...\n");
}
else
{
fprintf( stderr, "DEBUG...end.\n");
}
break;
#endif
default :
if ( ro_verbose == TRUE )
{
fprintf( stderr, "Command %d not found.\n", c_type );
fprintf( stderr, " line: <%s> \n", line );
}
break;
}
}
range( s )
char *s;
{
int num;
num=0;
while(isdigit(*s)) num=num*10+(*(s++)-'0');
if(num) ro_firstpage=num;
if(*s=='-')
{
s++;
num=0;
while(isdigit(*s)) num=num*10+(*(s++)-'0');
if(num) ro_lastpage=num;
}
else ro_lastpage = ro_firstpage;
}
ro_min( n1, n2 )
int n1, n2;
{
if ( n1 > n2 )
{
return n2;
}
else
{
return n1;
}
}
ro_max( n1, n2 )
int n1, n2;
{
if ( n1 < n2 )
{
return n2;
}
else
{
return n1;
}
}
memfill( b, n, c )
char *b;
int n;
char c;
{
register int x;
char *y;
y = b;
for ( x = 0; x < n; ++x )
{
*y = c;
}
}